import { URLS } from '@akinon/next/data/urls';
import { Metadata, AsyncPageProps } from '@akinon/next/types';
import logger from '@akinon/next/utils/log';
import { notFound } from 'next/navigation';
type PrettyUrlResult = {
matched: boolean;
path?: string;
pk?: number;
};
const resolvePrettyUrlHandler =
(pathname: string, ip: string | null) => async () => {
let results = [] as { old_path: string }[];
let prettyUrlResult: PrettyUrlResult = {
matched: false
};
try {
const requestUrl = URLS.misc.prettyUrls(`/${pathname}/`);
logger.debug(`Resolving pretty url`, { pathname, requestUrl, ip });
const start = Date.now();
const apiResponse = await fetch(requestUrl, {
next: {
revalidate: 0
}
});
const data = await apiResponse.json();
({ results } = data);
const end = Date.now();
console.warn('Pretty url response time', end - start, requestUrl);
const matched = results.length > 0;
const [{ old_path: path } = { old_path: '' }] = results;
let pk;
if (matched) {
const pkRegex = /\/(\d+)\/$/;
const match = path.match(pkRegex);
pk = match ? parseInt(match[1]) : undefined;
}
prettyUrlResult = {
matched,
path,
pk
};
logger.trace('Pretty url result', { prettyUrlResult, ip });
} catch (error) {
logger.error('Error resolving pretty url', { error, pathname, ip });
}
return prettyUrlResult;
};
export async function generateMetadata(props: AsyncPageProps) {
const params = await props.params;
let result: Metadata = {};
const { prettyurl } = params;
const pageSlug = prettyurl
.filter((x) => !x.startsWith('searchparams'))
.join('/');
const searchParams = new URLSearchParams(
decodeURIComponent(
prettyurl
.find((x) => x.startsWith('searchparams'))
?.replace('searchparams%7C', '')
) ?? {}
);
const prettyUrlResult = await resolvePrettyUrlHandler(pageSlug, null)();
if (!prettyUrlResult.matched) {
return notFound();
}
const commonProps = {
params: Promise.resolve({
...params,
pk: prettyUrlResult.pk
}),
searchParams: Promise.resolve(searchParams)
};
try {
if (prettyUrlResult.path.startsWith('/product/')) {
await import('@product/[pk]/page').then(async (module) => {
result = await module['generateMetadata']?.(commonProps as any);
});
}
if (prettyUrlResult.path.startsWith('/group-product/')) {
await import('@group-product/[pk]/page').then(async (module) => {
result = await module['generateMetadata']?.(commonProps as any);
});
}
if (prettyUrlResult.path.startsWith('/category/')) {
await import('@category/[pk]/page').then(async (module) => {
result = await module['generateMetadata']?.(commonProps as any);
});
}
if (prettyUrlResult.path.startsWith('/special-page/')) {
await import('@special-page/[pk]/page').then(async (module) => {
result = await module['generateMetadata']?.(commonProps as any);
});
}
if (prettyUrlResult.path.startsWith('/flat-page/')) {
await import('@flat-page/[pk]/page').then(async (module) => {
result = await module['generateMetadata']?.(commonProps as any);
});
}
// eslint-disable-next-line no-empty
} catch (error) {}
return result;
}
export const dynamic = 'force-static';
export const revalidate = 300;
export default async function Page(props) {
const params = await props.params;
const { prettyurl } = params;
const pageSlug = prettyurl
.filter((x) => !x.startsWith('searchparams'))
.join('/');
const urlSearchParams = new URLSearchParams(
decodeURIComponent(
prettyurl
.find((x) => x.startsWith('searchparams'))
?.replace('searchparams%7C', '')
) ?? {}
);
const searchParams = {};
for (const [key, value] of urlSearchParams.entries() as unknown as Array<
[string, string]
>) {
if (!searchParams[key]) {
searchParams[key] = [];
}
searchParams[key].push(value);
}
const result = await resolvePrettyUrlHandler(pageSlug, null)();
if (!result.matched) {
return notFound();
}
const commonProps = {
params: {
...params,
pk: result.pk
},
searchParams: urlSearchParams
} as any;
if (result.path.startsWith('/category/')) {
const CategoryPage = (await import('@category/[pk]/page')).default;
return ;
}
if (result.path.startsWith('/product/')) {
const ProductPage = (await import('@product/[pk]/page')).default;
return ;
}
if (result.path.startsWith('/group-product/')) {
const GroupProduct = (await import('@group-product/[pk]/page')).default;
return ;
}
if (result.path.startsWith('/special-page/')) {
const SpecialPage = (await import('@special-page/[pk]/page')).default;
return ;
}
if (result.path.startsWith('/flat-page/')) {
const FlatPage = (await import('@flat-page/[pk]/page')).default;
return ;
}
return null;
}